package com.zheng.api.server.service;


import com.zheng.api.common.constant.ApiConstant;
import com.zheng.api.server.domain.CaptchaReqParam;
import com.zheng.api.server.domain.CaptchaVerifyParam;
import com.zheng.common.util.RedisUtil;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Random;


@Service("apiServerCaptchaService")
public class ApiServerCaptchaService {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ApiServerCaptchaService.class);

    private static final String[] codeBase= {"0","1","2","3","4","5","6","7","8","9"};
    //codeBase= {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};

    private static Random rand= new Random();
    /** 验证码字符数 */
    private static int charCount = 6;
    /** 验证码超时门限(秒) */
    private static int expire = 60*2;
    /** 验证码验证错误限制次数 */
    private static int verifyErrorCount = 5;
    /** 验证码验证错误限制解锁时间 */
    private static int verifyErrorExpire = 60*60*2;
    /**
     * 缓存模块前缀
     */
    @Value("${Redis.CacheModule}")
    private String cacheModule;

    public ApiServerCaptchaService(){
        logger.info("正在构建验证码生成与验证服务");
    }

    public CaptchaReqParam getVerifyCode(String cacheKey, String codeType) {
        CaptchaReqParam req = new CaptchaReqParam();
        req.setCaptcha("");
        String keyPath = cacheModule + ":" + ApiConstant.CAPTCH_RANDOM_CODE + ":" + ApiConstant.CAPTCH_RANDOM_CODE_CODE + cacheKey;
        String keyErrorCountPath = cacheModule + ":" + ApiConstant.CAPTCH_RANDOM_CODE + ":" + ApiConstant.CAPTCH_RANDOM_CODE_COUNT + cacheKey;

        //判断缓存中有没有对应的key,如果有说明获取过于频繁
        if (RedisUtil.exists(keyPath)){
            req.setMessage("请勿频繁获取验证码");
            return req;
        }
        int errCount = 0 ;
        try{
            errCount = Integer.parseInt(RedisUtil.get(keyErrorCountPath));
        }catch(Exception e){
            errCount = 0;
        }
        if(errCount > verifyErrorCount){
            req.setMessage("由于验证失败次数达到限制，暂时禁止获取验证码");
            return req;
        }
        RedisUtil.set(keyErrorCountPath,String.valueOf(errCount+1),verifyErrorExpire);

        StringBuffer sb= new StringBuffer();
        for(int i=0; i<charCount; i++){
            int randInt= Math.abs(rand.nextInt());
            sb.append(codeBase[randInt % codeBase.length]);
        }
        //单次验证码放入redis缓存
        RedisUtil.set(keyPath,sb.toString(),expire);

        req.setCaptcha(sb.toString());
        req.setMessage("获取验证码成功");
        return req;
    }

    public boolean doVerify(CaptchaVerifyParam param) {

            String keyPath = cacheModule + ":" + ApiConstant.CAPTCH_RANDOM_CODE + ":" + ApiConstant.CAPTCH_RANDOM_CODE_CODE + param.getKey();
            String keyErrorCountPath = cacheModule + ":" + ApiConstant.CAPTCH_RANDOM_CODE + ":" + ApiConstant.CAPTCH_RANDOM_CODE_COUNT + param.getKey();

            if (!RedisUtil.exists(keyPath)) {
                return false;
            }
            if (!RedisUtil.get(keyPath).equals(param.getCaptcha())){
                //验证码验证错误总次数放入redis缓存
                int errCount = 0 ;
                try{
                    errCount = Integer.parseInt(RedisUtil.get(keyErrorCountPath));
                }catch(Exception e){
                    errCount = 0;
                }
                RedisUtil.set(keyErrorCountPath,String.valueOf(errCount+1),verifyErrorExpire);
                return false;
            }
            return true;
    }

}
